#include "imglib/downsample_impl.h"
#include "imglib/imageclass.h"
#include "imglib/bitmap.h"

namespace img {

#define INSTANTIATE(IR, OR) \
template \
void downsample(IR const & ir, OR & or, unsigned scale_x, unsigned scale_y); \
template \
void upsample(IR const & ir, OR & or, unsigned scale_x, unsigned scale_y);

INSTANTIATE(mono_byte_image, mono_byte_image);
INSTANTIATE(byte_image, byte_image);
INSTANTIATE(argb_byte_image, argb_byte_image);
INSTANTIATE(mono_float_image, mono_float_image);
INSTANTIATE(float_image, float_image);
INSTANTIATE(small_byte_image, small_byte_image);
INSTANTIATE(small_float_image, small_float_image);

#undef INSTANTIATE

template <>
void downsample(bitmap const & ir, bitmap & or, unsigned scale_x, unsigned scale_y)
{ 
	if (scale_x == 1 && scale_y == 1) {
		or = ir;
		return;
	}
	or.resize(ir.width() / scale_x, ir.height() / scale_y);

	unsigned half_square = scale_x * scale_y / 2;
	bitmap::iterator out;
	for (out = or.begin(); out != or.end(); ++out) {
		unsigned sum = 0;
		unsigned base_y = out.y() * scale_y;
		for (unsigned y = base_y; y < base_y + scale_y; ++y) {
			unsigned base_x = out.x() * scale_x;
			for (unsigned x = base_x; x < base_x + scale_x; ++x)
				sum += ir(x, y) ? 1 : 0;
		}
		*out = sum > half_square;
	}
}

// no specialization required
template void upsample(bitmap const & ir, bitmap & or, unsigned scale_x, unsigned scale_y);

} //namespace img
